package net.sevear.chaos.download
{
	import de.popforge.utils.SprintfUtil;
	
	import flash.events.Event;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	
	import net.sevear.chaos.event.SourceProxyEvent;
	import net.sevear.chaos.vo.TrackInfo;
	
	public class GoogleMusicProxy extends SourceProxy
	{
		/**
		 *  template = "http://www.google.cn/music/songstreaming?id=%s&cd&sig=%s&output=xml"
            flashplayer_key = "c51181b7f9bfce1ac742ed8b4a1ae4ed"
            sig = hashlib.md5(flashplayer_key + self.id).hexdigest()
            url = template % (self.id, sig)
            urlopener = urllib.urlopen(url)
            xml = urlopener.read()
            dom = minidom.parseString(xml)
            self.parse_node(dom.getElementsByTagName("songStreaming")[0])
			 * */
		
		/**
		 *  def musicdownload(id):
        '''获取下载地址'''
        
        template = "http://www.google.cn/music/top100/musicdownload?id=%s"
        url = template % id
        urlopener = urllib.urlopen(url)
        html = urlopener.read()
        matches = re.search('<a href="/(music/top100/url[^"]+)">', html)
        if matches is not None:
            return "http://www.google.cn/%s" % matches.group(1).replace("&amp;", "&")
        else:
            # TODO 短时间内请求次数太多了，可能出现验证码
            return ""
		**/
		protected var  SEARCH_URL:String;
		protected var  GET_SONG_INFO_URL:String;
		
		protected static const GETTING_SEARCH_RST:int = 1;
		protected static const GETTING_SEARCH_RST_ARTIST:int = 2;
		protected static const GETTING_SONG_INFO:int = 3;
		protected static const GETTING_MP3_URL:int = 4;
		
		public function GoogleMusicProxy(type:int)
		{
			super(type);
			initURLs();
		}
		
		protected function initURLs():void{
			SEARCH_URL = "http://www.google.cn/music/search?cat=song&q=%s&start=%d&num=%d&output=xml";
			GET_SONG_INFO_URL = "http://www.google.cn/music/top100/musicdownload?id=%s";
		}
		
		override public function searchSongNew(track:TrackInfo):void{
			if(enable && track!=null){
				try{
					timer.reset();
					loader.close();
				}catch(e:Error){
					
				}
				
				timer.start();
				curtrack = track;
				var url:String = SprintfUtil.sprintf(SEARCH_URL,curtrack.name,0,30);
				stepIdx = GETTING_SEARCH_RST;
				loader.load(new URLRequest(encodeURI(url)));
			}else{
				dispatchEvent(new SourceProxyEvent(SourceProxyEvent.SERVICE_BREAK_DOWN));
			}
		}
		
		private function searchWithArtist():void{
			var url:String = SprintfUtil.sprintf(SEARCH_URL,curtrack.name+" "+curtrack.artistName,0,30);
			stepIdx = GETTING_SEARCH_RST_ARTIST;
			loader.load(new URLRequest(encodeURI(url)));
		}
		
		override protected function onComplete(e:Event=null):void{
			var rstStr:String = (e.currentTarget as URLLoader).data as String;
			switch(stepIdx){
				case GETTING_SEARCH_RST:
					handleXML(rstStr,searchWithArtist);
					break;
				case GETTING_SEARCH_RST_ARTIST:
					handleXML(rstStr);
					break;
				case GETTING_MP3_URL:
					//			matches = re.search('<a href="/(music/top100/url[^"]+)">', html)
					//			if matches is not None:
					//			return "http://www.google.cn/%s" % matches.group(1).replace("&amp;", "&")
					//			else:
					//			# TODO 短时间内请求次数太多了，可能出现验证码
					//			return ""
					var matches:Array = rstStr.match(/<a href="\/(music\/top100\/url[^"]+)">/);
					if(matches!=null && matches.length>=2){
						var url:String = SprintfUtil.sprintf("http://www.google.cn/%s",(matches[1] as String).replace(/&amp;/g, "&"));
						dispatchEvent(new SourceProxyEvent(SourceProxyEvent.FOUND_URL,url,sourceType));
						timer.stop();
					}else{
						//# TODO 短时间内请求次数太多了，可能出现验证码 or 国外ip
						dispatchEvent(new SourceProxyEvent(SourceProxyEvent.NOT_FOUND_URL));
						timer.stop();
					}
					break;
			}
		}
		
		private function handleXML(rstStr:String,nextFindFunc:Function = null):void{
			try{
				var rstXML:XML = new XML(rstStr);
				var fittestSong:XML = selectFittestSong(rstXML);
				if(fittestSong!=null) 
					getDownLoadURL(fittestSong);
				else{
					if(nextFindFunc!=null){
						var rstCount:int = parseInt(rstXML.estimatedResultCount);
						if(rstCount>30){
							nextFindFunc();
						}else{
							dispatchEvent(new SourceProxyEvent(SourceProxyEvent.NOT_FOUND_URL));
							timer.stop();
						}
							
					}else{
						dispatchEvent(new SourceProxyEvent(SourceProxyEvent.NOT_FOUND_URL));
						timer.stop();
					}
				}
			}catch(e:Error){
				trace("Error ocurred when parse google result xml :",e.message);
				dispatchEvent(new SourceProxyEvent(SourceProxyEvent.NOT_FOUND_URL));
				timer.stop();
			}
		}
		private function selectFittestSong(xml:XML):XML{
			var songList:Array = [];
			var highestPoint:int;
			var highestSong:XML;
			for each (var song:XML in xml..songList.song) {
				var point:int = getMatchPoint(curtrack.name,song.name.toString());
				if(point<=0) continue;
				var artistPoint:int = getMatchPoint(curtrack.artistName,song.artist.toString());
				if(artistPoint<=0){
					continue;
				}else point +=artistPoint;
				var albumPoint:int =getMatchPoint(curtrack.albumName,song.album.toString());
				if(point>highestPoint && song.canBeDownloaded.toString()=="true"){
					highestPoint = point;
					highestSong = song;
				}
				if(highestPoint == FULL_MATCH*3){
					break;
				}
			}    
			return highestSong;
		}
		
		protected static const FULL_MATCH:int = 100;
		protected static const INCLUDE_PART:int = 50;
		protected function getMatchPoint(searchCondition:String,rstStr:String):int{
			var point:int = 0;
			if(searchCondition == rstStr){
				point = FULL_MATCH;
			}else{
				if(searchCondition.length>=rstStr.length){
					rstStr.replace(/'()-,+/g,' ');
					if(searchCondition.search(rstStr)>=0){
						//还需要考虑下要不要减分
//						var minusPoint:int = 
						point = INCLUDE_PART;
					}else{
						//NOT FOUND
					}
				}else{
					searchCondition.replace(/\'()-,+/g,' ');
					if(rstStr.search(searchCondition)>=0){
						//还需要考虑下要不要减分
						//						var minusPoint:int = 
						point = INCLUDE_PART;
					}else{
						//NOT FOUND
					}
				}
			}
			
			return point;
		}
		
		private function getDownLoadURL(song:XML):void{
			var id:String = song.id.toString();
			var url:String = SprintfUtil.sprintf(GET_SONG_INFO_URL,id);
			stepIdx = GETTING_MP3_URL;
			loader.load(new URLRequest(encodeURI(url)));
		}
		
	}
}